package com.mpb.prj.practice;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.regex.Pattern;

import org.expasy.jpl.utils.file.JPLFileFinder;
import org.expasy.jpl.utils.math.JPLStatScoreCalculator;

import de.proteinms.xtandemparser.xtandem.Peptide;
import de.proteinms.xtandemparser.xtandem.PeptideMap;
import de.proteinms.xtandemparser.xtandem.Spectrum;
import de.proteinms.xtandemparser.xtandem.XTandemFile;

public class JPLFDRCalculation {

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) {
		JPLFDRCalculation obj = new JPLFDRCalculation();
		obj.calculateFDR(args[0], args[1], null);
	}

	public double calculateFDR(String directory, String regex)
			throws IOException {
		return calculateFDR(directory, regex, null);
	}

	/*
	 * 
	 * C:\\DATA\\UDAY\\SWETHA\\project\\PROJECT_TEST\\OUT new_output.xml
	 */

	public double calculateFDR(String directory, String regex, String inputXml) {

		/** List of all spectrum files */
		ArrayList<File> files = new ArrayList<File>();

		try {
			files = JPLFileFinder.getFiles(directory, regex);
		} catch (FileNotFoundException e) {
			System.out.println(e.toString());
		}
		ArrayList<Double> decoyScores = new ArrayList<Double>();
		ArrayList<Double> targetScores = new ArrayList<Double>();
		for (File file : files) {
			System.out.println("XTandem output file: " + file.getPath()); // output
			// file
			// concatenated
			int targetCnt = 0;
			int decoyCnt = 0;
			boolean isDecoy = false;
			try {
				XTandemFile parser = new XTandemFile(file.getPath()); // the
				// path
				// of
				// the
				// file
				ArrayList<Spectrum> spectra = parser.getSpectraList();
				PeptideMap pepMap = parser.getPeptideMap();
				for (Spectrum spec : spectra) {
					int scanNr = spec.getSpectrumId(); // spectrumId
					int specNr = spec.getSpectrumNumber(); // spectrumNumber
					double pmz = spec.getPrecursorMh(); // precursor mass
					int Z = spec.getPrecursorCharge(); // precursor charge
					String protein = spec.getLabel();
					if (Pattern.matches("^DECOY_.*", protein)) {
						decoyCnt++;
						isDecoy = true;
					} else {
						targetCnt++;
						isDecoy = false;
					}

					Peptide peptide = null;
					String pepSeqs = "";
					double eValue = 0.0;
					double hScore = 0.0;
					try {
						peptide = pepMap.getAllPeptides(specNr).get(0);
						pepSeqs = peptide.getDomainSequence();
						eValue = peptide.getDomainExpect();
						hScore = peptide.getDomainHyperScore();
						if (isDecoy)
							decoyScores.add(hScore);
						else
							targetScores.add(hScore);
						// System.out.println(specNr+"\t"+scanNr+"\t"+pmz+"\t"+Z+"\t"+eValue+"\t"+hScore+"\t"+protein+"\t"+pepSeqs);
					} catch (Exception e) {
					}
				}
			} catch (Exception e) {
				System.out.println(e.toString());
			}
			double fdr = (1.0 * decoyCnt) / targetCnt; // FDR calculation(no
			// need)
			System.out.println("FDR = " + fdr);
		}

		JPLStatScoreCalculator stats = new JPLStatScoreCalculator();
		stats.setNegativeAllScores(decoyScores, targetScores);

		Double maxScoreValue = -10000.0;
		try {
			stats.calcScoreBinParamsFromData();
			ArrayList<Double> fdr = stats.getFDR();
			ArrayList<Double> scores = stats.getScoreBins();

			// {
			// JPLClusterReporter.setScoreStatDirectory(directory);
			// JPLClusterReporter.writeScoreStats(stats, "");
			// }

			System.out.println("scores.size = " + scores.size());
			System.out.println("fdr.size = " + fdr.size());
			// define index for fdr threshold

			if (fdr.size() == 0 && scores.size() == 0)
				return maxScoreValue;

			int idx_0_1 = fdr.size() - 1;
			int idx_0_05 = fdr.size() - 1;
			int idx_0_01 = fdr.size() - 1;
			for (int i = 0; i < fdr.size(); i++) {
				if (idx_0_1 == fdr.size() - 1 && fdr.get(i) < 0.1) {
					idx_0_1 = i;
				}
				if (idx_0_05 == fdr.size() - 1 && fdr.get(i) < 0.05) {
					idx_0_05 = i;
				}
				if (idx_0_01 == fdr.size() - 1 && fdr.get(i) < 0.01) {
					idx_0_01 = i;
				}
			}

			double scoreThresh_0_1 = 0;
			double scoreThresh_0_05 = 0;
			double scoreThresh_0_01 = 0;

			if (fdr.size() > 0) {
				scoreThresh_0_1 = scores.get(idx_0_1);
				scoreThresh_0_05 = scores.get(idx_0_05);
				scoreThresh_0_01 = scores.get(idx_0_01);
			}

			// System.out.println("Score at 0.1 FDR : "+scoreThresh_0_1);
			// System.out.println("Score at 0.05 FDR : "+scoreThresh_0_05);
			// System.out.println("Score at 0.01 FDR : "+scoreThresh_0_01);

			int cnt_0_1 = 0;
			int cnt_0_05 = 0;
			int cnt_0_01 = 0;

			for (Double score : targetScores) {
				if (score >= scoreThresh_0_1)
					cnt_0_1++;
				if (score >= scoreThresh_0_05)
					cnt_0_05++;
				if (score >= scoreThresh_0_01)
					cnt_0_01++;
			}

			System.out.println("Nr of PSM at 0.05 FDR : " + cnt_0_05);
			
			for (int i = 0; i < scores.size(); i++) {
				if (scores.get(i) > maxScoreValue)
					maxScoreValue = scores.get(i);
			}		

		}
		catch (OutOfMemoryError e) {			
			handleException(inputXml);			
		}
		catch(NullPointerException e){			
			handleException(inputXml);			
		}
		return maxScoreValue;

		// System.out.println("Nr of PSM at 0.1 FDR : "+cnt_0_1);
		// System.out.println("Nr of PSM at 0.05 FDR : "+cnt_0_05);
		// System.out.println("Nr of PSM at 0.01 FDR : "+cnt_0_01);
		// return scoreThresh_0_05;
	}

	private void handleException(String inputXml){
		System.out.println("Exception handled");
		File fileImproperXml = new File("ImproperXml.txt");
		FileWriter fw;
		try {
			fw = new FileWriter(fileImproperXml, true);
			FileReader reader = new FileReader(new File(inputXml));
			int i = 0;
			while ((i = reader.read()) != -1) {
				// System.out.print((char)i);
				fw.write(i);
			}

			fw.flush();
			fw.close();

		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}
}